package com.xish.api;

import com.xish.spring.exception.Common200Exception;
import com.xish.spring.exception.Common200ExceptionHandler;
import com.xish.util.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
public class ErrorController {

    private static final Logger LOG = LoggerFactory.getLogger(ErrorController.class);

    @Autowired
    private Common200ExceptionHandler common200ExceptionHandler;

    @RequestMapping("/_error")
    public ModelAndView render(HttpServletRequest request, HttpServletResponse response) {
        if (!DispatcherType.ERROR.equals(request.getDispatcherType())) {
            return null;
        }

        int code = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
        String message = (String) request.getAttribute(RequestDispatcher.ERROR_MESSAGE);
        Exception exception = (Exception) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);

        if (exception != null) {
            Throwable cause = exception.getCause();
            if ((cause != null) && (cause instanceof Common200Exception)) {
                common200ExceptionHandler.handle(response, (Common200Exception) cause);
                return null;
            }

            if (code >= 500) {
                LOG.error("Internal error.", exception);
            } else {
                LOG.warn("Exception caught, type:{}", exception.getClass().getName());
            }
        }

        response.setStatus(code);
        response.setContentType(MediaType.APPLICATION_JSON);
        try {
            message = (message == null) ? "" : message.replaceAll("\"", "'");

            StringBuilder builder = new StringBuilder();
            builder.append("{ \"code\": ").append(code).append(", \"message\": \"").append(message).append("\"}");
            response.getWriter().print(builder.toString());
        } catch (IOException e) {
            LOG.error("IOException error.", e);
        }

        return null;
    }
}
